package com.hitfm.iplay;

import java.io.File;
import java.io.IOException;
import java.util.Random;

import android.app.Service;
import android.content.Intent;
import android.content.res.Resources.NotFoundException;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Binder;
import android.os.IBinder;
import android.provider.MediaStore.Audio.Media;
import android.util.Log;
import android.widget.Toast;

import com.hitfm.iplay.db.RecentplayDAO;
import com.hitfm.iplay.util.BitmapRadius;

public class MusicPlayerService extends Service {
	private final IBinder mBinder = new LocalBinder();

	private static MediaPlayer mMediaPlayer = null;
	private boolean isRandom = true;

	public static final String PLAYER_PREPARE_END = "com.hitfm.iplay.prepared";
	public static final String PLAY_COMPLETED = "com.hitfm.iplay.playcompleted";
	public static final String PLAY_PAUSE = "com.hitfm.iplay.pause";
	public static final String PLAY_CONTINUE = "com.hitfm.iplay.continue";
	public static final String ERROR = "com.hitfm.iplay.error";
	public static final String UPDATE = "com.hitfm.iplay.update";
	public static final String DELETE = "com.hitfm.iplay.delete";
	public static final int ID_INIT = -1;
	public static final int NONEID = 0;

	public static String singer = "";
	public static String songname = "";
	public static String album;
	private static RecentplayDAO recentplayDAO;

	MediaPlayer.OnCompletionListener mCompleteListener = new MediaPlayer.OnCompletionListener() {
		public void onCompletion(MediaPlayer mp) {
			broadcastEvent(PLAY_COMPLETED);
		}
	};

	MediaPlayer.OnPreparedListener mPrepareListener = new MediaPlayer.OnPreparedListener() {
		public void onPrepared(MediaPlayer mp) {
			broadcastEvent(PLAYER_PREPARE_END);
			recentplayDAO.open();
			recentplayDAO.insertData(getMusicPath(), singer, songname, album);
			recentplayDAO.close();
		}
	};

	MediaPlayer.OnErrorListener mOnErrorListener = new MediaPlayer.OnErrorListener() {
		@Override
		public boolean onError(MediaPlayer mp, int what, int extra) {
			broadcastEvent(ERROR);
			stopPlaying();
			MusicPlayerService.this.onCreate();
			if (what == MediaPlayer.MEDIA_ERROR_UNKNOWN) {
				Toast.makeText(MusicPlayerService.this, R.string.unknowerror, Toast.LENGTH_SHORT).show();
				Log.i("test", "UnknownError");
			} else if (what == MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK) {
				Log.i("test", "MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK");
			} else if (what == MediaPlayer.MEDIA_ERROR_SERVER_DIED) {
				Log.i("test", "MEDIA_ERROR_SERVER_DIED");
			}
			return true;
		}
	};

	private String path;
	private static int id = ID_INIT;
	private boolean isPaused = false;
	private int albumID;

	private static boolean isPlayingNotFromLocalList = false;

	private static boolean isUpdate = false;

	private static Cursor mCursor;

	private static MusicPlayerApp musicPlayerApp = null;

	private void broadcastEvent(String what) {
		Intent i = new Intent(what);
		sendBroadcast(i);
	}

	private void initDatabase() {
		recentplayDAO = new RecentplayDAO(this);
	}

	public void onCreate() {
		super.onCreate();
		mMediaPlayer = new MediaPlayer();
		setListeners();
		initDatabase();
	}

	private void setListeners() {
		mMediaPlayer.setOnPreparedListener(mPrepareListener);
		mMediaPlayer.setOnCompletionListener(mCompleteListener);
		mMediaPlayer.setOnErrorListener(mOnErrorListener);
	}

	public class LocalBinder extends Binder {
		public MusicPlayerService getService() {
			return MusicPlayerService.this;
		}
	}

	public IBinder onBind(Intent intent) {
		return mBinder;
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		stopPlaying();
		if (null != recentplayDAO) {
			recentplayDAO.close();
			recentplayDAO.close();
		}
	}

	public void setMusicPath(String path) {

		try {
			this.path = path;
			mMediaPlayer.reset();
			mMediaPlayer.setDataSource(path);
			mMediaPlayer.prepare();
		} catch (IOException e) {
			return;
		} catch (IllegalArgumentException e) {
			return;
		}
	}

	public void start() {
		if (isPaused) {
			broadcastEvent(PLAY_CONTINUE);
		}
		isPaused = false;
		try {
			mMediaPlayer.start();
		} catch (IllegalStateException e) {
			mMediaPlayer.release();
			mMediaPlayer = new MediaPlayer();
			setListeners();
			e.printStackTrace();
			onCreate();
		}
	}

	public void stop() {
		isPaused = false;
		try {
			mMediaPlayer.stop();
		} catch (IllegalStateException e) {
			e.printStackTrace();
			onCreate();
		}
	}

	public void pause() {
		isPaused = true;
		broadcastEvent(PLAY_PAUSE);
		try {
			mMediaPlayer.pause();
		} catch (IllegalStateException e) {
			e.printStackTrace();
			onCreate();
		}
	}

	public boolean isPlaying() {
		try {
			if (id == ID_INIT) {
				return false;
			}
			return mMediaPlayer.isPlaying();
		} catch (Exception e) {
			e.printStackTrace();
			onCreate();
		}
		return false;
	}

	public int getDuration() {
		return mMediaPlayer.getDuration();
	}

	public int getPosition() {
		return mMediaPlayer.getCurrentPosition();
	}

	public void setPosition(int msec) {
		mMediaPlayer.seekTo(msec);
	}

	public long seek(long whereto) {
		mMediaPlayer.seekTo((int) whereto);
		return whereto;
	}

	public String getMusicPath() {
		return path;
	}

	public int getId() {
		return id;
	}

	public static void setId(int id) {
		MusicPlayerService.id = id;
	}

	public String getInfo() {
		if (singer == null || ("").equals(singer)) {
			return new File(getMusicPath()).getName();
		}
		return (id + 1) + "." + singer + "--" + songname;
	}

	/**
	 * 
	 * @param isNext
	 *            true:next; false:pre
	 */
	public void nextOrPreSong(boolean isNext) {
		try {
			musicPlayerApp = (MusicPlayerApp) getApplication();
			if (null == musicPlayerApp.getCursor()) {
				musicPlayerApp.initCursor();
			}
			if (id == ID_INIT) {
				mCursor = musicPlayerApp.getAllCursor();
			} else {
				mCursor = musicPlayerApp.getCursor();
			}
			if (0 == mCursor.getCount()) {
				return;
			}
			int temp = 0;
			File tempFile = new File("");
			String url = "";
			while (!tempFile.exists()) {
				if (isRandom) {
					Random random = new Random(System.currentTimeMillis());
					temp = random.nextInt(mCursor.getCount());
				} else if (isNext) {
					temp = ((id + 1) < mCursor.getCount()) ? (id + 1) : 0;
				} else if (!isNext) {
					temp = ((id - 1) >= 0) ? (id - 1) : (mCursor.getCount() - 1);
				}
				id = temp;
				if (mCursor.moveToPosition(id)) {
					url = mCursor.getString(mCursor.getColumnIndex(Media.DATA));
					tempFile = new File(url);
				}
			}
			if ("" == url) {
				return;
			}
			setMusicPath(url);
			singer = mCursor.getString(mCursor.getColumnIndex(Media.ARTIST));
			songname = mCursor.getString(mCursor.getColumnIndex(Media.TITLE));
			album = mCursor.getString(mCursor.getColumnIndex(Media.ALBUM));
			setAlbumID(mCursor);
			mMediaPlayer.start();

		} catch (NotFoundException e) {
			Toast.makeText(this, R.string.nosong, Toast.LENGTH_SHORT).show();
			broadcastEvent(ERROR);
			e.printStackTrace();
		} catch (Exception e) {
			broadcastEvent(ERROR);
			e.printStackTrace();
		}
	}

	public boolean isRandom() {
		return isRandom;
	}

	public void setRandom(boolean isRandom) {
		this.isRandom = isRandom;
	}

	public Bitmap getAlbumArt(int id, int radius) {
		String album_art = null;
		try {
			if (isPlayingNotFromLocalList) {
				MusicInfoController musicInfoController = MusicInfoController.getInstance(musicPlayerApp);
				Cursor cursor = musicInfoController.getSingleSongByURL(getMusicPath());
				if (cursor != null && cursor.getCount() == 1) {
					cursor.moveToFirst();
					setAlbumID(cursor);
				}
				if (cursor != null) {
					cursor.close();
					cursor = null;
				}
				isPlayingNotFromLocalList = false;
			}
			if (id == NONEID) {
				id = this.albumID;
			}
			String mUriAlbums = "content://media/external/audio/albums";
			String[] projection = new String[] { "album_art" };
			Cursor cur = getContentResolver().query(Uri.parse(mUriAlbums + "/" + Integer.toString(id)), projection, null, null,
					null);
			if (cur.getCount() > 0 && cur.getColumnCount() > 0) {
				cur.moveToNext();
				album_art = cur.getString(0);
			}
			cur.close();
			cur = null;
		} catch (Exception e) {
			e.printStackTrace();
			Toast.makeText(this, R.string.nosongimage, Toast.LENGTH_SHORT).show();
		}
		try {
			if (album_art != null) {
				return BitmapRadius.toRoundCorner(BitmapFactory.decodeFile(album_art), radius);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		new BitmapFactory();
		return BitmapFactory.decodeResource(getResources(), R.drawable.default_song_img);

	}

	public boolean isPaused() {
		return isPaused;
	}

	public void stopPlaying() {
		try {
			mMediaPlayer.stop();
			mMediaPlayer.release();
			if (null != musicPlayerApp) {
				musicPlayerApp.closeCursor();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void setAlbumID(Cursor c) {
		this.albumID = c.getInt(c.getColumnIndexOrThrow(Media.ALBUM_ID));
	}

	public static void setSinger(String singer) {
		MusicPlayerService.singer = singer;
	}

	public static void setSongname(String songname) {
		MusicPlayerService.songname = songname;
	}

	public static String getSinger() {
		return singer;
	}

	public static String getSongname() {
		return songname;
	}

	public static String getAlbum() {
		return album;
	}

	public static void setAlbum(String album) {
		MusicPlayerService.album = album;
	}

	public void setUpdateSongInfo(boolean b) {
		if (b == true) {
			broadcastEvent(UPDATE);
		}
		isUpdate = true;
	}

	public void setDeleteSong(boolean b) {
		if (b == true) {
			broadcastEvent(DELETE);
		}
		isUpdate = true;
		id = ID_INIT;
	}

	public static boolean isUpdate() {
		if (isUpdate) {
			isUpdate = false;
			return true;
		}
		return false;
	}

	public void setPlayingNotFromLocalList(boolean b) {
		isPlayingNotFromLocalList = true;
	}
}
